package cn.cuilan.test.thread;

/**
 * 奇数 Odd
 * 偶数 Even
 * 两个线程交替打印
 *
 * @author zhangyan
 * @since 2023/3/9
 */
public class OddEvenPrint {

    private static final Object monitor = new Object();
    private volatile int count;

    public OddEvenPrint(int count) {
        this.count = count;
    }

    /**
     * 任意数字，两个线程奇偶交替输出
     *
     * @param maxNum 最大数
     */
    public void print(int maxNum) {
        synchronized (monitor) {
            while (count <= maxNum) {
                // 第一个线程进来之后，先输出
                System.out.println(Thread.currentThread().getName() + ": " + count);
                // 自增
                count++;
                // 唤醒另一个线程
                monitor.notifyAll();
                try {
                    // 当前线程阻塞
                    monitor.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // count = 10 之后，while() 循环不再执行，
            // 此时子线程被阻塞未被唤醒，导致 main 线程一直处于等待状态
            monitor.notifyAll();
        }
    }

    public static void main(String[] args) {
        OddEvenPrint oddEven = new OddEvenPrint(1);

        new Thread(() -> oddEven.print(10), "odd").start();
        new Thread(() -> oddEven.print(10), "even").start();
    }

}
